<template>
  <div class="app-container">
    <el-row :gutter="20">
      <el-col :span="24">
        <el-card>
          <div slot="header" class="clearfix">
            <span>Redis功能监控大屏</span>
            <el-button style="float: right; padding: 3px 0" type="text" @click="refreshData">刷新数据</el-button>
          </div>
        </el-card>
      </el-col>
    </el-row>

    <el-row :gutter="20" style="margin-top: 20px;">
      <!-- 用户访问热度排行 -->
      <el-col :span="12">
        <el-card>
          <div slot="header" class="clearfix">
            <span>热门用户排行</span>
          </div>
          <div id="hotUsersChart" style="height: 400px;"></div>
        </el-card>
      </el-col>

      <!-- 用户行为分析饼图 -->
      <el-col :span="12">
        <el-card>
          <div slot="header" class="clearfix">
            <span>用户行为分析</span>
          </div>
          <div id="userBehaviorPie" style="height: 400px;"></div>
        </el-card>
      </el-col>
    </el-row>

    <el-row :gutter="20" style="margin-top: 20px;">
      <!-- 实时访问趋势 -->
      <el-col :span="24">
        <el-card>
          <div slot="header" class="clearfix">
            <span>实时访问趋势</span>
          </div>
          <div id="accessTrendChart" style="height: 400px;"></div>
        </el-card>
      </el-col>
    </el-row>

    <el-row :gutter="20" style="margin-top: 20px;">
      <!-- 接口访问限流监控 -->
      <el-col :span="12">
        <el-card>
          <div slot="header" class="clearfix">
            <span>接口限流监控</span>
          </div>
          <div id="rateLimitChart" style="height: 400px;"></div>
          <div class="rate-limit-test">
            <el-button type="primary" @click="testRateLimit">测试限流</el-button>
            <span v-if="rateLimitResult">{{rateLimitResult}}</span>
          </div>
        </el-card>
      </el-col>

      <!-- 分布式锁监控 -->
      <el-col :span="12">
        <el-card>
          <div slot="header" class="clearfix">
            <span>分布式锁测试</span>
          </div>
          <div id="lockTestChart" style="height: 350px;"></div>
          <div class="lock-test">
            <el-button type="primary" @click="testDistributedLock">测试分布式锁</el-button>
            <span v-if="lockTestResult">{{lockTestResult}}</span>
          </div>
        </el-card>
      </el-col>
    </el-row>

    <!-- 用户访问热力图 -->
    <el-row :gutter="20" style="margin-top: 20px;">
      <el-col :span="24">
        <el-card>
          <div slot="header" class="clearfix">
            <span>用户访问热力图</span>
          </div>
          <user-heatmap-chart />
        </el-card>
      </el-col>
    </el-row>

    <!-- 消息发布订阅测试区域 -->
    <el-row :gutter="20" style="margin-top: 20px;">
      <el-col :span="24">
        <el-card>
          <div slot="header" class="clearfix">
            <span>消息发布订阅</span>
          </div>
          <div class="pub-sub-test">
            <el-input v-model="pubSubMessage" placeholder="请输入消息内容" style="width: 300px; margin-right: 10px;"></el-input>
            <el-button type="primary" @click="publishMessage">发布消息</el-button>
          </div>
          <div style="margin-top: 10px;">
            <el-table :data="messageHistory" style="width: 100%">
              <el-table-column prop="time" label="时间" width="180"></el-table-column>
              <el-table-column prop="channel" label="频道" width="180"></el-table-column>
              <el-table-column prop="message" label="消息内容"></el-table-column>
            </el-table>
          </div>
        </el-card>
      </el-col>
    </el-row>
  </div>
</template>

<script>
import * as echarts from 'echarts'
import UserHeatmapChart from './UserHeatmapChart.vue'
import {
  getHotUsers,
  getBehaviorStats,
  testRateLimit,
  testDistributedLock,
  publishMessage as pubSubPublishMessage,
  getRateLimitStats
} from '@/api/redis'

export default {
  name: 'RedisMonitor',
  components: {
    UserHeatmapChart
  },
  data() {
    return {
      hotUsersChart: null,
      userBehaviorPieChart: null,
      accessTrendChart: null,
      rateLimitChart: null,
      lockTestChart: null,
      requestCounts: Array(10).fill(0),
      lockTestResults: [],
      rateLimitResults: [],
      rateLimitResult: '',
      lockTestResult: '',
      pubSubMessage: '',
      messageHistory: [],
      charts: {} // 存储所有图表实例
    }
  },
  mounted() {
    this.initCharts()
    this.loadAllData()

    // 每30秒刷新一次数据
    this.refreshTimer = setInterval(() => {
      this.refreshData()
    }, 30000)

    // 模拟实时数据变化
    this.simulationTimer = setInterval(() => {
      this.simulateRealTimeData()
    }, 5000)
  },
  beforeDestroy() {
    // 清除定时器
    clearInterval(this.refreshTimer)
    clearInterval(this.simulationTimer)

    // 销毁图表实例
    Object.keys(this.charts).forEach(key => {
      if (this.charts[key]) {
        this.charts[key].dispose()
      }
    })
  },
  methods: {
    initCharts() {
      // 初始化热门用户排行图
      this.charts.hotUsers = echarts.init(document.getElementById('hotUsersChart'))

      // 初始化用户行为分析饼图
      this.charts.userBehaviorPie = echarts.init(document.getElementById('userBehaviorPie'))

      // 初始化实时访问趋势图
      this.charts.accessTrend = echarts.init(document.getElementById('accessTrendChart'))

      // 初始化接口限流监控图
      this.charts.rateLimit = echarts.init(document.getElementById('rateLimitChart'))

      // 初始化分布式锁测试图
      this.charts.lockTest = echarts.init(document.getElementById('lockTestChart'))
    },

    loadAllData() {
      this.loadHotUsers()
      this.loadUserBehavior()
      this.initAccessTrendChart()
      this.initRateLimitChart()
      this.initLockTestChart()
    },

    async loadHotUsers() {
      try {
        const response = await getHotUsers()
        if (response.code === 200 && response.data) {
          const users = response.data
          const usernames = users.map(item => item.user ? item.user.username : `用户${item.rank}`)
          const scores = users.map(item => item.score || 0)

          this.charts.hotUsers.setOption({
            title: {
              text: '热门用户访问排行'
            },
            tooltip: {
              trigger: 'axis',
              axisPointer: {
                type: 'shadow'
              }
            },
            xAxis: {
              type: 'value'
            },
            yAxis: {
              type: 'category',
              data: usernames,
              inverse: true
            },
            series: [
              {
                name: '访问热度',
                type: 'bar',
                data: scores,
                label: {
                  show: true,
                  position: 'right'
                },
                itemStyle: {
                  color: function(params) {
                    const colorList = ['#c23531','#2f4554','#61a0a8','#d48265','#91c7ae']
                    return colorList[params.dataIndex % colorList.length]
                  }
                }
              }
            ]
          })
        }
      } catch (error) {
        console.error('加载热门用户数据失败', error)
        // 使用模拟数据
        this.loadHotUsersMock()
      }
    },

    loadHotUsersMock() {
      const usernames = ['用户1', '用户2', '用户3', '用户4', '用户5']
      const scores = [120, 98, 85, 70, 60]

      this.charts.hotUsers.setOption({
        title: {
          text: '热门用户访问排行 (模拟数据)'
        },
        tooltip: {
          trigger: 'axis',
          axisPointer: {
            type: 'shadow'
          }
        },
        xAxis: {
          type: 'value'
        },
        yAxis: {
          type: 'category',
          data: usernames,
          inverse: true
        },
        series: [
          {
            name: '访问热度',
            type: 'bar',
            data: scores,
            label: {
              show: true,
              position: 'right'
            },
            itemStyle: {
              color: function(params) {
                const colorList = ['#c23531','#2f4554','#61a0a8','#d48265','#91c7ae']
                return colorList[params.dataIndex % colorList.length]
              }
            }
          }
        ]
      })
    },

    async loadUserBehavior() {
      try {
        const response = await getBehaviorStats()
        if (response.code === 200 && response.data) {
          // 数据可能在data中，也可能在extend中
          const stats = response.data.dailyStats || {}
          const behaviors = Object.keys(stats)
          const values = behaviors.map(key => stats[key])

          this.charts.userBehaviorPie.setOption({
            title: {
              text: '用户行为分布',
              left: 'center'
            },
            tooltip: {
              trigger: 'item',
              formatter: '{a} <br/>{b} : {c} ({d}%)'
            },
            legend: {
              orient: 'vertical',
              left: 'left',
              data: behaviors
            },
            series: [
              {
                name: '行为次数',
                type: 'pie',
                radius: '55%',
                center: ['50%', '60%'],
                data: behaviors.map((key, index) => {
                  return {name: key, value: values[index]}
                }),
                emphasis: {
                  itemStyle: {
                    shadowBlur: 10,
                    shadowOffsetX: 0,
                    shadowColor: 'rgba(0, 0, 0, 0.5)'
                  }
                }
              }
            ]
          })
        }
      } catch (error) {
        console.error('加载用户行为数据失败', error)
        // 使用模拟数据
        this.loadUserBehaviorMock()
      }
    },

    loadUserBehaviorMock() {
      const behaviors = ['view', 'like', 'comment', 'share']
      const values = [235, 120, 86, 64]

      this.charts.userBehaviorPie.setOption({
        title: {
          text: '用户行为分布 (模拟数据)',
          left: 'center'
        },
        tooltip: {
          trigger: 'item',
          formatter: '{a} <br/>{b} : {c} ({d}%)'
        },
        legend: {
          orient: 'vertical',
          left: 'left',
          data: behaviors
        },
        series: [
          {
            name: '行为次数',
            type: 'pie',
            radius: '55%',
            center: ['50%', '60%'],
            data: behaviors.map((key, index) => {
              return {name: key, value: values[index]}
            }),
            emphasis: {
              itemStyle: {
                shadowBlur: 10,
                shadowOffsetX: 0,
                shadowColor: 'rgba(0, 0, 0, 0.5)'
              }
            }
          }
        ]
      })
    },

    initAccessTrendChart() {
      const now = new Date()
      const times = []
      const data = []

      for (let i = 9; i >= 0; i--) {
        const time = new Date(now - i * 30000) // 每30秒一个点
        times.push(time.toLocaleTimeString('zh-CN', {hour: '2-digit', minute:'2-digit', second:'2-digit'}))
        data.push(Math.floor(Math.random() * 100) + 10) // 模拟数据
      }

      this.charts.accessTrend.setOption({
        title: {
          text: '实时访问趋势'
        },
        tooltip: {
          trigger: 'axis'
        },
        xAxis: {
          type: 'category',
          data: times
        },
        yAxis: {
          type: 'value'
        },
        series: [
          {
            name: '访问量',
            type: 'line',
            smooth: true,
            data: data,
            markPoint: {
              data: [
                { type: 'max', name: '最大值' },
                { type: 'min', name: '最小值' }
              ]
            },
            areaStyle: {
              opacity: 0.3
            }
          }
        ]
      })

      this.requestCounts = data
      this.accessTrendTimes = times
    },

    async initRateLimitChart() {
      try {
        const response = await getRateLimitStats()
        if (response.code === 200 && response.data && response.data.length > 0) {
          const statsData = response.data
          
          // 提取数据
          const categories = statsData.map(item => item.interface)
          const passed = statsData.map(item => item.passed)
          const limited = statsData.map(item => item.limited)
          
          this.charts.rateLimit.setOption({
            title: {
              text: '接口限流监控'
            },
            tooltip: {
              trigger: 'axis',
              axisPointer: {
                type: 'shadow'
              }
            },
            legend: {
              data: ['通过请求', '限流请求']
            },
            grid: {
              left: '3%',
              right: '4%',
              bottom: '3%',
              containLabel: true
            },
            xAxis: {
              type: 'category',
              data: categories
            },
            yAxis: {
              type: 'value'
            },
            series: [
              {
                name: '通过请求',
                type: 'bar',
                stack: '总量',
                emphasis: {
                  focus: 'series'
                },
                data: passed
              },
              {
                name: '限流请求',
                type: 'bar',
                stack: '总量',
                emphasis: {
                  focus: 'series'
                },
                data: limited,
                itemStyle: {
                  color: '#c23531'
                }
              }
            ]
          })
          
          this.rateLimitResults = []
        } else {
          // 获取后端数据失败，使用默认数据
          this.initRateLimitChartWithMockData()
        }
      } catch (error) {
        console.error('获取限流统计数据失败', error)
        // 使用默认数据
        this.initRateLimitChartWithMockData()
      }
    },
    
    // 使用模拟数据初始化图表
    initRateLimitChartWithMockData() {
      const categories = ['接口1', '接口2', '接口3', '接口4', '接口5']
      const allowed = [42, 35, 28, 49, 33]
      const rejected = [8, 5, 12, 1, 7]

      this.charts.rateLimit.setOption({
        title: {
          text: '接口限流监控（模拟数据）'
        },
        tooltip: {
          trigger: 'axis',
          axisPointer: {
            type: 'shadow'
          }
        },
        legend: {
          data: ['通过请求', '限流请求']
        },
        grid: {
          left: '3%',
          right: '4%',
          bottom: '3%',
          containLabel: true
        },
        xAxis: {
          type: 'category',
          data: categories
        },
        yAxis: {
          type: 'value'
        },
        series: [
          {
            name: '通过请求',
            type: 'bar',
            stack: '总量',
            emphasis: {
              focus: 'series'
            },
            data: allowed
          },
          {
            name: '限流请求',
            type: 'bar',
            stack: '总量',
            emphasis: {
              focus: 'series'
            },
            data: rejected,
            itemStyle: {
              color: '#c23531'
            }
          }
        ]
      })
      
      this.rateLimitResults = []
    },

    initLockTestChart() {
      const data = [
        {value: 85, name: '加锁成功'},
        {value: 15, name: '加锁失败'}
      ]

      this.charts.lockTest.setOption({
        title: {
          text: '分布式锁测试',
          left: 'center'
        },
        tooltip: {
          trigger: 'item'
        },
        legend: {
          orient: 'vertical',
          left: 'left'
        },
        series: [
          {
            name: '锁测试',
            type: 'pie',
            radius: '50%',
            data: data,
            emphasis: {
              itemStyle: {
                shadowBlur: 10,
                shadowOffsetX: 0,
                shadowColor: 'rgba(0, 0, 0, 0.5)'
              }
            }
          }
        ]
      })
    },

    simulateRealTimeData() {
      // 更新访问趋势图
      const now = new Date()
      this.requestCounts.shift()
      this.requestCounts.push(Math.floor(Math.random() * 100) + 10)

      this.accessTrendTimes.shift()
      this.accessTrendTimes.push(now.toLocaleTimeString('zh-CN', {hour: '2-digit', minute:'2-digit', second:'2-digit'}))

      this.charts.accessTrend.setOption({
        xAxis: {
          data: this.accessTrendTimes
        },
        series: [{
          data: this.requestCounts
        }]
      })
    },

    refreshData() {
      this.loadAllData()
    },

    async testRateLimit() {
      try {
        const response = await testRateLimit()
        if (response.code === 200) {
          this.rateLimitResult = response.data.message
          
          // 更新接口限流统计图表
          this.initRateLimitChart()
        }
      } catch (error) {
        this.rateLimitResult = '请求失败：' + error.message
      }
    },

    async testDistributedLock() {
      try {
        const response = await testDistributedLock()
        if (response.code === 200) {
          const result = response.data
          this.lockTestResult = result.message

          // 更新分布式锁测试图
          const lockChart = this.charts.lockTest
          const oldData = lockChart.getOption().series[0].data
          const newData = [
            {value: oldData[0].value + (result.locked ? 1 : 0), name: '加锁成功'},
            {value: oldData[1].value + (result.locked ? 0 : 1), name: '加锁失败'}
          ]
          lockChart.setOption({
            series: [{
              data: newData
            }]
          })
        }
      } catch (error) {
        this.lockTestResult = '请求失败：' + error.message
      }
    },

    async publishMessage() {
      if (!this.pubSubMessage.trim()) {
        this.$message.warning('请输入消息内容')
        return
      }

      try {
        const response = await pubSubPublishMessage('user:actions', this.pubSubMessage)

        if (response.code === 200) {
          this.$message.success('消息发布成功')

          // 添加到消息历史
          const now = new Date()
          this.messageHistory.unshift({
            time: now.toLocaleTimeString(),
            channel: 'user:actions',
            message: this.pubSubMessage
          })

          // 最多保留10条记录
          if (this.messageHistory.length > 10) {
            this.messageHistory.pop()
          }

          this.pubSubMessage = ''
        }
      } catch (error) {
        this.$message.error('消息发布失败：' + error.message)
      }
    }
  }
}
</script>

<style scoped>
.app-container {
  padding: 20px;
}
.rate-limit-test, .lock-test, .pub-sub-test {
  margin-top: 20px;
  display: flex;
  align-items: center;
}
.rate-limit-test span, .lock-test span {
  margin-left: 10px;
}
</style>
 